/*
 *  lib-smv: Matrix - Vector Library targeted to Structural Mechanics Problems
 *  Copyright (C) 2006-2008  St.Brcic, Lj.Zugic
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
/** @file Jacobi.h
 *  @brief Definition of class Jacobi - solution of the eigenvalue problem
 *
 *  EIGENVALUE PROBLEMS:  Class JACOBI  
 *  STANDARD EIGENVALUE PROBLEMS A*x = L*x
 * 
 *  Jacobi transformation 
 */ 

#ifndef _JACOBI_H
#define _JACOBI_H

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cassert>
#include <string>
#include "Arrays.h"
#include "iArrays.h"

using namespace std;

namespace smv_lib
{
/**
* \brief class Jacobi
*
*  EIGENVALUE ANALYSIS, STANDARD AND GENERALIZED PROBLEMS
*  ( A*x = L*x and A*x = L*B*x )
*
*  Jacobi transformation
*  symmetric and positive definite matrices
*  (mainly according to "Numerical Recipes in C").
*/
class Jacobi
{
  private:
    //! Matrix A for the standard eigenvalue problem A*x = Lambda*x
    Matrix A;
    //! Matrix B for the generalized eigenvalue problem A*x = Lambda*B*x
    Matrix B;
    //! Order of matrices A and B
    int N;
    //! Modal matrix: columns of V are eigenvectors
    Matrix V;
    //! Vector of eigenvalues: Spectral vector (matrix)
    Vector d;

    //--- control data
    //! Indicator: true if matrix A is given - for standard problem
    bool isMatrix_A;
    //! Indicator: true if matrix B is given - for generalized problem
    bool isMatrix_B;
    //! Indicator: true if the problem is solved
    bool isCalculated;

  public:
    //! empty (default) constructor
    Jacobi(void);
    //! constructor for the standard complete problem
    Jacobi(Matrix& a);
    //! constructor for the generalized complete problem
    Jacobi(Matrix& a, Matrix& b);
    //! destructor
    ~Jacobi(void);

    //--------- set and get functions (in case of a default constructor)
    //! set Matrix A (for standard problem)
    void setMatrix_A(Matrix& a);
    //! set Matrices A and B (for generalized problem)
    void setMatrix_B(Matrix& a, Matrix& b);

    //--------- calculate eigenvectors and eigenvalues
    void calculate();
    //--------- give the results
    Matrix giveModalMatrix();
    Vector giveSpectrum();

  private:
    //! standard Jacobi transformation
    void stJacobi();
    //! sort obtained eigenvecetors / eigenvalues
    void eigsrt_Jacobi();
    //! generalized Jacobi transformation
    void genJacobi();
};

//===================== external functions for the Standard eigenvalue problem Ax = Lx
void eigsrt_Jacobi (Vector& d, Matrix& V);
//! standard Jacobi's transformation
void stJacobi (Matrix& A, Vector& d, Matrix& V, int *nrot);

}   // end of namespace smv_lib

#endif //  _JACOBI_H

//=============================== end of file
